package de.playmee;

import java.util.HashSet;
import java.util.Set;

import android.content.ContentUris;
import android.content.res.Resources;
import android.net.Uri;

import de.playmee.enums.Mood;
import de.playmee.enums.Season;
import de.playmee.enums.TimeOfDay;

public class Track {
	
	public final static int DUMMY_ALBUM_ART = R.drawable.dummy_album_art;

	private long id_device;
	private long id_database;
	private String data = "";

	private String artist = "";
	private String title = "";
	private String album = "";
	private String artLink = "";
	private int release;
	private long duration;
	private int bpm;

	private Set<Mood> moods = new HashSet<Mood>();
	private Set<TimeOfDay> timesOfDay = new HashSet<TimeOfDay>();
	private Set<Season> seasons = new HashSet<Season>();
	private Set<Weather.Condition> weatherConditions = new HashSet<Weather.Condition>();
	
	private Status status = Status.UNRATED;
	
	public enum Status {
		UNRATED,
		UPLOADING,
		RATED
	}

	/**
	 * sets the locale id
	 * 
	 * @param id
	 */
	public Track(long id, String data, Resources res) {
		this.id_device = id;
		this.data = data;
	}

	/**
	 * sets the global id
	 * 
	 * @param id_database
	 */
	public void setIdDatabase(long id_database) {
		this.id_database = id_database;
	}

	/**
	 * sets the artist
	 * 
	 * @param artist
	 */
	public void setArtist(String artist) {
		this.artist = artist;
	}

	/**
	 * sets the title
	 * 
	 * @param title
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/**
	 * sets the album
	 * 
	 * @param album
	 */
	public void setAlbum(String album) {
		this.album = album;
	}
	
	/**
	 * sets the link to the album art of an external database
	 * 
	 * @param artLink
	 */
	public void setArtLink(String artLink) {
		this.artLink = artLink;
	}

	/**
	 * sets the release
	 * 
	 * @param release
	 */
	public void setRelease(int release) {
		this.release = release;
	}

	/**
	 * sets the duration
	 * 
	 * @param duration
	 */
	public void setDuration(long duration) {
		this.duration = duration;
	}

	/**
	 * sets the beats per minute
	 * 
	 * @param bpm
	 */
	public void setBpm(int bpm) {
		this.bpm = bpm;
	}

	/**
	 * @return id_device
	 */
	public long getId() {
		return id_device;
	}

	/**
	 * @return id_database
	 */
	public long getIdDatabase() {
		return id_database;
	}
	
	/**
	 * @return data
	 */
	public String getData() {
		return data;
	}

	/**
	 * @return artist
	 */
	public String getArtist() {
		return artist;
	}

	/**
	 * @return title
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * @return album
	 */
	public String getAlbum() {
		return album;
	}
	
	/**
	 * @return artLink
	 */
	public String getArtLink() {
		return artLink;
	}

	/**
	 * @return release
	 */
	public int getRelease() {
		return release;
	}

	/**
	 * @return duration
	 */
	public long getDuration() {
		return duration;
	}

	/**
	 * @return bpm
	 */
	public int getBpm() {
		return bpm;
	}

	/**
	 * @return moods
	 */
	public Set<Mood> getMoods() {
		return moods;
	}

	/**
	 * @return timesOfDay
	 */
	public Set<TimeOfDay> getTimesOfDay() {
		return timesOfDay;
	}

	/**
	 * @return seasons
	 */
	public Set<Season> getSeasons() {
		return seasons;
	}

	/**
	 * @return weatherConditions
	 */
	public Set<Weather.Condition> getWeatherConditions() {
		return weatherConditions;
	}

	/**
	 * @return uri
	 */
	public Uri getURI() {
		return ContentUris.withAppendedId(
				android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
				id_device);
	}
	
	/**
	 * sets the status
	 * 
	 * @param status
	 */
	public void setStatus(Status status) {
		this.status = status;
	}
	
	/**
	 * @return status
	 */
	public Status getStatus() {
		return status;
	}
	
	/**
	 * @return true if track is unrated, false otherwise
	 */
	public boolean isUnrated() {
		return status == Status.UNRATED;
	}
	
	/**
	 * @return true if track is uploading, false otherwise
	 */
	public boolean isUploading() {
		return status == Status.UPLOADING;
	}
	
	/**
	 * @return true if track is rated, false otherwise
	 */
	public boolean isRated() {
		return status == Status.RATED;
	}
	
	/**
	 * @return true if the track has any context factory, false otherwise
	 */
	public boolean hasContextFactors() {
		return (!weatherConditions.isEmpty() || !moods.isEmpty()
				|| !seasons.isEmpty() || !timesOfDay.isEmpty());
	}
	
	/**
	 * @return formatted duration (mm:ss)
	 */
	public String getFormattedDuration() {
		long duration = getDuration();
		long ms = duration % 1000;
		duration /= 1000;
		long s = duration % 60;
		duration /= 60;
		long m = duration;
		
		if (ms > 500)
			s += 1;
		
		String min = (m < 10) ? "0"+m : ""+m;
		String sec = (s < 10) ? "0"+s : ""+s;
		
		return min + ":" + sec;
	}
	
	/**
	 * creates a string with all information about the channel
	 * 
	 * @return string
	 */
	public String getInfo() {
		// times of day
		String timesOfDay = "";
		for (TimeOfDay timeOfDay : getTimesOfDay()) {
			if (!timesOfDay.isEmpty()) {
				timesOfDay += ", ";
			}
			timesOfDay += timeOfDay.toString();
		}
		// seasons
		String seasons = "";
		for (Season season : getSeasons()) {
			if (!seasons.isEmpty()) {
				seasons += ", ";
			}
			seasons += season.toString();
		}
		// weather conditions
		String conditions = "";
		for (Weather.Condition condition : getWeatherConditions()) {
			if (!conditions.isEmpty()) {
				conditions += ", ";
			}
			conditions += condition.toString();
		}
		// moods
		String moods = "";
		for (Mood mood : getMoods()) {
			if (!moods.isEmpty()) {
				moods += ", ";
			}
			moods += mood.toString();
		}

		// create message
		String message = "Artist: " + getArtist()
				+ "\nTitle: " + getTitle()
				+ "\nAlbum: " + getAlbum()
				+ "\nRelease: " + getRelease()
				+ "\nDuration: " + getFormattedDuration()
				+ "\nTimes of day: " + timesOfDay
				+ "\nSeasons: " + seasons
				+ "\nWeather conditions: " + conditions
				+ "\nMoods: " + moods
				+ "\n\nID_Device: " + getId()
				+ "\nID_Database: " + getIdDatabase()
				+ "\n\nData: " + getData()
				+ "\n\nURI: " + getURI();
		return message;
	}
	
	/**
	 * two tracks are equal if they have the same global id
	 * 
	 * @see Object#equals(Object)
	 */
	@Override
	public boolean equals(Object o) {
		if (!(o instanceof Track)) {
			return false;
		}
		return getId() == ((Track) o).getIdDatabase();
	}
	
	/**
	 * @return hash code of the track
	 */
	public String getAlbumArtKey() {
		return artist + ";" + album;
	}
	
}
